<template>
	<div class="uploade_file_item">
		<div :class="['progress', progressClass]" :style="progressStyle" v-if="!file.completed"></div>
		<div class="wrapper">
			<div class="name">
				<i :class="{ checked: file.checked }" v-if="isCheck && file.success" @click="handleCheckedFile"></i>
				<span :title="file.name" @click="handleCheckedFile">{{ file.name }}</span>
			</div>
			<div class="size">{{ file.size | fileSizeFitler }}</div>
			<div class="status" v-html="fileStatusText"></div>
			<div class="handle">
				<button @click.prevent="handlePreviewFile" v-if="!isPreview && file.success">预览</button>
				<button @click.prevent="handleUploadFile" :disabled="!isCalcFinish" v-if="!file.completed">{{ uploadBtnName }}</button>
				<button @click.prevent="handleDeleteFile" :disabled="!isCalcFinish">删除</button>
			</div>
		</div>
	</div>
</template>

<script>
import { mapGetters } from 'vuex';
import { Message } from 'element-ui';
import computeFileMD5 from './calcMD5.js';
import { fileSizeFitler } from './filter.js';
import { deleteChunkedUpload, mergeChunkedUpload } from './config';
export default {
	props: {
		file: {
			type: Object,
			default () {
				return {};
			}
		},
		isCheck: Boolean
	},
	inject: ['autoUpload'],
	data() {
		return {
			isCalcFinish: false,
			isFirstUpload: true,
			fileStatusText: null,
			uploadProgress: 0,
			progressClass: '',
			uploadBtnName: '开始',
			isMergeSuccess: false
		};
	},
	filters: { fileSizeFitler },
	computed: {
		...mapGetters(['token']),
		fileInstance() {
			return this.file;
		},
		progressStyle() {
			let progress = this.uploadProgress;
			return {
				transform: `translateX(${progress - 100}%)`
			};
		},
		isPreview() {
			return !this.$listeners.preview;
		}
	},
	watch: {
		fileInstance: {
			handler(data) {
				this.uploadProgress = Math.round(data.progress() * 100);
				if(!data.completed) {
					if(this.isCalcFinish && !this.isFirstUpload) {
						if(data.paused) {
							this.uploadBtnName = '开始';
							this.fileStatusText = `<font color="#999">暂停上传</font>`;
						} else if(data.error) {
							this.uploadBtnName = '重试';
							this.fileStatusText = `<font color="#f00">上传出错</font>`;
							this.progressClass = 'error';
						} else {
							this.uploadBtnName = '暂停';
							this.fileStatusText = `上传 <font color="#f90">${this.uploadProgress}%</font>`;
						}
					}
				} else {
					if(data.merging && !this.isMergeSuccess) {
						this.isMergeSuccess = true;
						this.fileStatusText = `<font color="#06f">合并中</font>`;
						this.handleMergeChunked(data.fileId);
					} else if(data.success) {
						this.fileStatusText = `<font color="#67c23a">上传完成</font>`;
					}
				}
			},
			deep: true
		}
	},
	mounted() {
		let that = this;
		computeFileMD5(that.file, {
			init() {
				that.fileStatusText = '开始计算MD5';
			},
			progress(data) {
				that.fileStatusText = `MD5计算 <font color="#f90">${parseInt(data)}%</font>`;
			},
			finish(data) {
				that.isCalcFinish = true;
				that.file['md5Value'] = data.toUpperCase();
				if(that.autoUpload) {
					that.isFirstUpload = false;
					that.file.resume();
				} else {
					that.fileStatusText = `上传等待中`;
				}
			}
		});
	},
	methods: {
		//预览文件
		handlePreviewFile() {
			this.$emit('preview', this.file.fileId);
		},
		//上传操作
		handleUploadFile() {
			if(this.file.paused) {
				this.isFirstUpload = false;
				this.file.resume();
			} else if(this.file.error) {
				this.file.retry();
			} else {
				this.file.pause();
			}
		},
		//删除文件
		handleDeleteFile() {
			if(!this.isFirstUpload && !this.file.success) {
				this.deleteUploadChunks();
			} else {
				this.file.cancel();
			}
		},

		//删除上传文件分片
		async deleteUploadChunks() {
			let params = [this.file.fileId];
			let result = await deleteChunkedUpload(params, { Authorization: this.token }).then(res => res.data);
			if(result.code === '0') {
				this.file.cancel();
			} else {
				Message({
					type: 'error',
					message: result.msg,
					offset: 80
				});
			}
		},

		//合并上传文件分片
		async handleMergeChunked(id) {
			let result = await mergeChunkedUpload({ id }, { Authorization: this.token }).then(res => res.data);
			if(result.code === '0') {
				delete this.file.merging;
				this.$set(this.file, 'success', true);
				this.$set(this.file, 'checked', true);
			} else {
				Message({
					type: 'error',
					message: result.msg,
					offset: 80
				});
			}
		},

		//选中上传文件
		handleCheckedFile() {
			if(!this.isCheck) return false;
			if(!this.file.checked) {
				this.$set(this.file, 'checked', true);
			} else {
				this.$set(this.file, 'checked', false);
			}
		}
	}
};
</script>

<style scoped>
.uploade_file_item {
	line-height: 1;
	position: relative;
	border-radius: 3px;
	border: solid 1px #eee;
	margin-top: -1px;
	z-index: 0;
	overflow: hidden;
}

.uploade_file_item .progress {
	position: absolute;
	z-index: 1;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	transform: translateX(-100%);
	transition: transform 0.1s linear;
	background-color: var(--primary);
	opacity: 0.25;
}

.uploade_file_item .progress.error {
	background-color: #f00;
	opacity: 0.1;
}

.uploade_file_item .wrapper {
	display: flex;
	align-items: center;
	position: relative;
	z-index: 2;
	overflow: hidden;
	max-width: none;
	min-width: 0;
}

.uploade_file_item .name {
	display: flex;
	align-items: center;
	padding-left: 10px;
	flex: 1;
	overflow: hidden;
}

.uploade_file_item .name span {
	width: auto;
	line-height: 1;
	margin-left: 6px;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
	cursor: pointer;
	user-select: none;
}

.uploade_file_item .name i {
	width: 6px;
	height: 6px;
	padding: 3px;
	flex-shrink: 0;
	border: solid 2px #0063ca;
	cursor: pointer;
}

.uploade_file_item .name i.checked::before {
	display: block;
	width: 6px;
	height: 6px;
	content: '';
	background-color: #0063ca;
}

.uploade_file_item .status {
	width: 120px;
	margin-left: 10px;
}

.uploade_file_item .size {
	width: 80px;
	flex-shrink: 0;
	padding: 0 10px;
	text-align: right;
}

.uploade_file_item .handle {
	width: 110px;
	flex-shrink: 0;
	font-size: 0;
	padding: 10px;
	text-align: right;
}

.uploade_file_item .handle button {
	display: inline-block;
	font-size: 14px;
	line-height: 1;
	padding: 5px;
	outline: 0;
	border: none 0;
	color: var(--primary);
	background-color: transparent;
	vertical-align: top;
}

.uploade_file_item .handle button:hover {
	color: var(--primary-hover);
}

.uploade_file_item .handle button[disabled] {
	color: var(--primary-disabled);
	cursor: default;
}
</style>